# -*- coding: utf-8 -*-
'''
Author : super
dateTime: 2025/10/9 12:14
FileName:general_tool.py.py
'''
import sqlite3
from pathlib import Path
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header
import openpyxl
import os, random
from faker import Faker
from tools.log import Logger
from openpyxl.styles import Font, colors, Alignment
from PIL import Image
import string
import pymysql
import configparser
import hmac
import hashlib

logger = Logger().logger


# 阿里邮件配置
MailHostIp = "smtp.qiye.aliyun.com"                # 阿里邮箱SMTP服务器
MailHostPort = 465                        # SSL端口
MailSendUser = "gechao@yqn.com"          # 阿里邮箱地址
MailSendPasswd = "u0QfICCg7a0z7JcM"            # 阿里邮箱授权码

# # QQ邮箱配置
# MailHostIp = "smtp.qq.com"                # QQ邮箱SMTP服务器
# MailHostPort = 465                        # SSL端口
# MailSendUser = "1579101153@qq.com"          # 您的QQ邮箱地址
# MailSendPasswd = "jbdgomzwvnihgeed"            # QQ邮箱授权码(不是QQ密码!)



def hmacsha256(message, key):
    key_bytes = bytes(key, 'utf-8')
    message_bytes = bytes(message, 'utf-8')
    hmacsha256_str = hmac.new(key_bytes, message_bytes, digestmod=hashlib.sha256).hexdigest()
    return hmacsha256_str


class CaseFilePath:

    def __init__(self, file_parent_path=Path(__file__).resolve().parent.parent / 'case_data'):
        self._path = file_parent_path

    def get_file(self, file_name, patten='*'):
        file_ = [f for f in self._path.rglob(patten) if f.is_file and f.name == file_name]
        return file_

    def get_case_file(self, file_name):
        file = self.get_file(file_name=file_name if 'xlsx' in file_name else file_name + '.xlsx', patten='*.xlsx')
        if file:
            return file[0]
        else:
            logger.error(f'[{file_name}] 找不到该文件')
            raise FileNotFoundError('测试用例文件找不到')

    def get_json_case_file(self, file_name):
        file = self.get_file(file_name=file_name if 'json' in file_name else file_name + '.json', patten='*.json')
        if file:
            return file[0]
        else:
            logger.error(f'[{file_name}] 找不到该json用例')
            raise FileNotFoundError('测试用例文件找不到')


def sendMail(toUser, title, text):
    msg = MIMEText(text, 'plain', 'utf-8')
    msg['From'] = Header(MailSendUser)  # 发送者
    msg['To'] = Header(toUser)  # 接收者
    subject = title
    msg['Subject'] = Header(subject, 'utf-8')

    try:
        print(f"📧 开始发送邮件...")
        print(f"   SMTP服务器: {MailHostIp}:{MailHostPort}")
        print(f"   发件人: {MailSendUser}")
        print(f"   收件人: {toUser}")
        
        smtpobj = smtplib.SMTP_SSL(MailHostIp)
        # 建立连接
        smtpobj.connect(MailHostIp, MailHostPort)
        print(f"   ✅ SMTP连接成功")
        
        # 登录
        smtpobj.login(MailSendUser, MailSendPasswd)
        print(f"   ✅ SMTP登录成功")
        
        # 发送邮件
        smtpobj.sendmail(MailSendUser, toUser, msg.as_string())
        print("   ✅ 邮件发送成功")
        return True
        
    except smtplib.SMTPAuthenticationError as e:
        print(f"   ❌ SMTP认证失败: {e}")
        print(f"   请检查邮箱账号和密码是否正确")
        return False
        
    except smtplib.SMTPConnectError as e:
        print(f"   ❌ SMTP连接失败: {e}")
        print(f"   请检查SMTP服务器地址和端口")
        return False
        
    except smtplib.SMTPException as e:
        print(f"   ❌ SMTP错误: {e}")
        return False
        
    except Exception as e:
        print(f"   ❌ 发送邮件失败: {type(e).__name__}: {e}")
        return False
        
    finally:
        # 关闭服务器
        try:
            smtpobj.quit()
            print(f"   🔒 SMTP连接已关闭")
        except:
            pass


class ExcelOperation(object):
    '''
    excel数据操作
    '''

    def __init__(self, file_name):
        self.file_path = CaseFilePath().get_case_file(file_name)
        self.wb = openpyxl.load_workbook(self.file_path)  # 打开文件
        # 根据表名打开表

    def write(self, row, col, value, sheet_name, color=colors.BLACK):
        ws = self.wb[sheet_name]
        ws.cell(row, col).value = value  # 写入数据到指定单元格
        ws.cell(row, col).font = Font(color=color)
        ws.cell(row, col).alignment = Alignment(horizontal='left', vertical='top')

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        return self.wb.save(self.file_path)


class RandomCaseData:
    def __init__(self):
        self.fake = Faker(locale='zh_CN')

    def random_name(self):
        return self.fake.unique.name()

    @property
    def random_ssn(self):
        return self.fake.unique.ssn()

    @property
    def random_address(self):
        return self.fake.unique.address()

    @property
    def random_phone_number(self):
        return self.fake.unique.phone_number()

    def random_int(self, start=18, end=20, prefix=None):
        '''
        随机生成一串数字
        '''

        random_number = self.fake.random.randint(a=start, b=end)

        if prefix:
            return str(prefix) + str(random_number)
        else:
            return str(random_number)

    def random_string(self, min_length=18, max_length=20):
        '''
        生成长度在指定区间内的随机英文字符串
        '''
        random_length = self.fake.random_int(min=min_length, max=max_length)
        random_english_string = self.fake.pystr(min_chars=random_length, max_chars=random_length)
        return random_english_string

    @property
    def random_number(self):
        '''
        随机生成16为数字
        '''
        return self.fake.random_number(digits=16)

    @property
    def generate_random_16_chars(self, min_length=11, max_length=16):
        '''
        随机生成16位字符串包含字符与数字
        '''
        length = random.randint(min_length, max_length)
        letters = string.ascii_letters + string.digits
        random_string = ''.join(random.choice(letters) for _ in range(length))
        return random_string

    def generate_random_image(self):
        '''
        随机生成一张图片
        '''
        image = self.fake.image()
        image_data = image.split(';base64,')[-1]
        with open('random_image.png', 'wb') as f:
            f.write(image_data.decode('base64'))
        img = Image.open('random_image.png')
        img.show()


class ReadConf(object):

    def __init__(self, file_):
        self.cf = configparser.ConfigParser()
        self.file_path = file_
        self.cf.read(self.file_path, encoding='utf8')

    def get_conf(self, section):
        return dict(self.cf.items(section))

    def get_items(self, section):
        '''
        :param section:  section
        :return: [("option",value)]
        '''
        kv = self.cf.sections()
        return kv


if __name__ == '__main__':
    r = RandomCaseData()
    a = r.random_phone_number
    print(a)
